home *** CD-ROM | disk | FTP | other *** search
/ Aminet 40 / Aminet 40 (2000)(Schatztruhe)[!][Dec 2000].iso / Aminet / util / boot / loadppclib.lha / loadppclib / src / loadppclib.e < prev   
Encoding:
Text File  |  2000-09-02  |  6.0 KB  |  247 lines

  1. -> FILE: ESrc:Own/loadppclib.e          REV: 1 --- load ppc.library on BlizzPPC
  2. /* History
  3.    0      Started in September 2000.
  4.    1      2nd Sep: added WOS termination. added retry.
  5. */
  6.  
  7. OPT PREPROCESS
  8.  
  9. #define VERSION 'loadppclib 1.0.0 (2.9.2000)'
  10. #define LIBNAME 'ppc.library'
  11.  
  12. MODULE 'dos/dos','dos/doshunks','exec/memory','exec/execbase',
  13.        'graphics/gfxbase','exec/libraries','exec/resident',
  14.        'exec/execbase'
  15.  
  16. ENUM ARG_LIB,ARG_FORCE,NUMARGS
  17.  
  18. ENUM ER_OK,ER_PARAM,ER_NOMEM,ER_ALREADY,ER_NOBPPC,ER_NO0X0LIB,ER_WOS,
  19.      ER_LOADSEG,ER_NOTLIB,ER_NOTPPCLIB,ER_EMULLIB,ER_ADDPPCLIB
  20.  
  21. DEF array[NUMARGS]:ARRAY OF LONG
  22.  
  23. PROC main() HANDLE
  24.   DEF attnflags
  25.   DEF rdargs = NIL, name:PTR TO CHAR, ioerr, ret
  26.   DEF r, pname[64]:STRING
  27.   DEF wosbase = NIL:PTR TO lib, wosb, da0x0lib
  28.   DEF seglist = NIL, ids
  29.  
  30.   IF (KickVersion(37) = 0)
  31.     WriteF('This program requires AmigaOS 2.04+\n')
  32.     RETURN RETURN_FAIL
  33.   ENDIF
  34.  
  35.   attnflags := extattnflags(Int(execbase + $128))
  36.   IF ((attnflags AND AFF_68040) = 0)
  37.     PrintF('This program requires 68040+ CPU\n')
  38.     RETURN RETURN_FAIL
  39.   ENDIF
  40.  
  41.   -> test if it's there already...
  42.   Forbid()
  43.   ids := FindName(execbase + 378, LIBNAME)
  44.   Permit()
  45.   IF (ids) THEN Raise(ER_ALREADY)
  46.  
  47.   FOR r := 0 TO NUMARGS-1; array[r] := 0; ENDFOR
  48.   IF ((rdargs := ReadArgs('LIBRARY,FORCE/S',
  49.       array, NIL)) = NIL) THEN Raise(ER_PARAM)
  50.  
  51.   IF (array[ARG_LIB])
  52.     name := array[ARG_LIB]
  53.   ELSE
  54.     name := 'libs:' + LIBNAME
  55.   ENDIF
  56.  
  57.   -> see if the HW is there...
  58.   Forbid()
  59.   da0x0lib := FindName(execbase + 378,
  60.     IF (attnflags AND $80) THEN '68060.library' ELSE '68040.library')
  61.   ids := FindResident('BlizzardPPC.IDTag')
  62.   wosb := FindName(execbase + 378, 'powerpc.library')
  63.   Permit()
  64.   IF ((ids = NIL) AND (array[ARG_FORCE] = 0)) THEN Raise(ER_NOBPPC)
  65.   IF (da0x0lib = NIL) THEN Raise(ER_NO0X0LIB)
  66.  
  67.   IF (wosb)
  68.     IF (wosbase := OpenLibrary('powerpc.library', 14))
  69.       IF (array[ARG_FORCE] = 0) THEN Raise(ER_WOS)
  70.     ENDIF
  71.   ENDIF
  72.  
  73.   -> load the seglist
  74.   IF ((seglist := LoadSeg(name)) = NIL) THEN Raise(ER_LOADSEG)
  75.   IF (initseg({seglist}))
  76.     UnLoadSeg(seglist)
  77.  
  78.     -> retry, it seems to fail sometimes...
  79.     IF ((seglist := LoadSeg(name)) = NIL) THEN Raise(ER_LOADSEG)
  80.     IF (initseg({seglist})) THEN Raise(ER_ADDPPCLIB)
  81.   ENDIF
  82.  
  83.   -> succeeded & got wosbase?
  84.   IF ((seglist = NIL) AND (wosbase <> NIL))
  85.  
  86.     IF ((r := AllocMem(8, MEMF_PUBLIC)) = NIL) THEN Raise(ER_NOMEM)
  87.  
  88.     -> patch LIB_OPEN to return zero.
  89.     Forbid()
  90.     PutLong(r, $70004E75) ->  moveq #0,d0 / rts
  91.     PutLong(r + 4, SetFunction(wosbase, -$6, r))
  92.     CacheClearU()
  93.     Permit()
  94.   ENDIF
  95.  
  96. EXCEPT DO
  97.   IF (exception)
  98.     IF (ioerr := IoErr()) THEN PrintFault(ioerr, NIL)
  99.     GetProgramName(pname, StrMax(pname) - 1)
  100.     PrintF('\s: \s\s\n', pname,
  101.            ListItem(['', 'argument error',
  102.                     'no memory',
  103.                     'library already in memory',
  104.                     'Blizzard PPC not found, FORCE to override',
  105.                     '680x0.library not loaded',
  106.                     'WarpUP found in memory, FORCE to override',
  107.                     'could not loadseg', 'file is not a library',
  108.                     'file is not a ',
  109.                     'file is a ppclibemu ',
  110.                     'could not add '
  111.                     ], exception),
  112.            IF ((exception = ER_NOTLIB) OR (exception = ER_NOTPPCLIB) OR
  113.                (exception = ER_EMULLIB)) THEN LIBNAME ELSE ''
  114.            )
  115.     ret := RETURN_ERROR
  116.   ELSE
  117.     ret := RETURN_OK
  118.   ENDIF
  119.  
  120.   IF (seglist) THEN UnLoadSeg(seglist)
  121.   IF (wosbase) THEN CloseLibrary(wosbase)
  122.   IF (rdargs) THEN FreeArgs(rdargs)
  123. ENDPROC ret
  124.  
  125. CHAR '$VER: ',VERSION,0
  126.  
  127.  
  128. PROC initseg(seglist:PTR TO LONG)
  129.   DEF r, segment:PTR TO LONG, tag:PTR TO rt, seglen
  130.   DEF ids, emul = 0, islibrary = 0, isthelib = 0
  131.  
  132.   -> do the stuff in forbid...
  133.   Forbid()
  134.   IF (FindName(execbase + 378, LIBNAME) = NIL)
  135.  
  136.     -> find the ROMTag in seglist
  137.     segment := ^seglist * 4
  138.  
  139.     WHILE (^seglist <> NIL) AND (segment <> NIL)
  140.  
  141.       seglen := segment[-1] - 8 - SIZEOF rt
  142.       tag := segment + 2
  143.  
  144.       WHILE (^seglist <> NIL) AND (seglen > 0)
  145.  
  146.         ADDQ.L  #2,tag
  147.         SUBQ.L  #2,seglen
  148.  
  149.         IF ((tag.matchword = RTC_MATCHWORD) AND
  150.           (tag.matchtag) = tag)
  151.  
  152.           islibrary := 1
  153.  
  154.           -> check name
  155.           IF (StrCmp(tag.name, LIBNAME))
  156.  
  157.             isthelib := 1
  158.  
  159.             -> check for ppclibemu
  160.             IF (ids := tag.idstring)
  161.               FOR r := 24 TO StrLen(ids) - 8
  162.                 IF (StrCmp(ids + r, 'mulation', STRLEN))
  163.                   emul := 1
  164.                 ENDIF
  165.               ENDFOR
  166.             ENDIF
  167.  
  168.             IF (emul = 0)
  169.               -> init the resident.
  170.               -> NOTE: emulates ROM-init with seglist = NIL
  171.               InitResident(tag, NIL)
  172.  
  173.               -> did it work?
  174.               IF (FindName(execbase + 378, LIBNAME))
  175.                 -> success! prevent unloading
  176.                 ^seglist := NIL
  177.               ENDIF
  178.             ENDIF
  179.           ENDIF
  180.         ENDIF
  181.       ENDWHILE
  182.       segment := segment[] * 4
  183.     ENDWHILE
  184.   ENDIF
  185.  
  186.   Permit()
  187.  
  188.   IF (^seglist)
  189.     IF (islibrary = 0) THEN Raise(ER_NOTLIB)
  190.     IF (isthelib = 0) THEN Raise(ER_NOTPPCLIB)
  191.     IF (emul) THEN Raise(ER_EMULLIB)
  192.   ENDIF
  193. ENDPROC ^seglist
  194.  
  195. PROC extattnflags(flags)
  196.   DEF orren = 0
  197.   IF ((flags AND AFF_68040) AND ((flags AND $80) = 0))
  198.     MOVE.L  A5,-(A7)
  199.     LEA     check060(PC),A5
  200.     JSR     -$78(A6)
  201.     JSR     -$1E(A6)
  202.     JSR     -$7E(A6)
  203.     MOVE.L  (A7)+,A5
  204.     MOVE.L  D0,orren
  205.   ENDIF
  206.   RETURN flags OR orren
  207.  
  208. check060:
  209.   INT     $4E7A,$8801      -> MOVEC VBR,A0
  210.   MOVE.L  $10(A0),-(A7)
  211.   MOVE.L  $2C(A0),-(A7)
  212.   MOVE.L  A0,-(A7)
  213.   LEA     c060illegal(PC),A1
  214.   MOVE.L  A1,$10(A0)
  215.   MOVE.L  A1,$2C(A0)
  216.   INT     $F518,$F4F8,$F4D8
  217.  
  218.   MOVEQ   #0,D0
  219.  
  220.   INT     $4E7A,$0008   -> MOVEC BUSCR,D0
  221.   INT     $4E7A,$0808   -> MOVEC PCR,D0
  222.  
  223.   NOP
  224.   NOP
  225.   MOVEQ   #1,D0
  226.  
  227. c060exit_illegal:
  228.   MOVE.L  (A7)+,A0
  229.   MOVE.L  (A7)+,$2C(A0)
  230.   MOVE.L  (A7)+,$10(A0)
  231.   INT     $F518,$F4F8,$F4D8
  232.   TST.L   D0
  233.   BEQ.S   c060_no060
  234.  
  235.   MOVE.L  #$00000080,D0
  236.  
  237. c060_no060:
  238.   NOP
  239.   RTE
  240.  
  241. c060illegal:
  242.   LEA     c060exit_illegal(PC),A0
  243.   MOVE.L  A0,2(A7)
  244.   NOP
  245.   RTE
  246. ENDPROC
  247.